<template>
  <div>
    <div
      ref="progress"
      class="progress"
      @pointermove.capture="handleMouseMove"
      @pointerleave="handleMouseLeave"
      @pointerdown="handleMouseDown"
      @pointerup="handleMouseUp"
    >
      <div
        class="passed"
        :style="{
      width:passed+'px',
      backgroundImage:`url(${svgPath})`
    }"
      />
      <div class="left" />
      <div v-if="showHint" class="hintLine" :style="{
      left:hintPos-1+'px'
    }" />
    </div>
    <div class="hint" :style="{
      left:hintLeft+'px'
    }">
      <svg
        width="100%"
        height="100%"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 600 600"
      >
        <g ref="g" opacity="0">
          <path ref="timeDisplay" fill="rgba(0,0,0,0.5)" stroke="gray" stroke-width="10" />
          <text
            fill="white"
            stroke="white"
            ref="text"
            x="300"
            text-anchor="middle"
            y="200"
            font-family="微软雅黑"
            font-size="150"
          >{{currentTime}}</text>
        </g>
      </svg>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import Svg from "@/assets/passedbkgnd.svg";
import * as d3 from "d3";
@Component
export default class ProgressBar extends Vue {
  private width: number = 0;
  private passed: number = 0;
  private showHint: boolean = false;
  private hintPos: number = 0;
  private hintLeft: number = 0;
  private svgX: number = 300;
  private mouseLeave: boolean = false;
  private mouseDown: boolean = false;
  private mouseHover: boolean = false;
  private showingFlag: boolean = false;
  private leavingFlag: boolean = false;
  private svgPath: string = Svg;
  private currentTime: string = "00:00";
  private canUpdateProgress: boolean = true;
  @Watch("$store.state.progress")
  private proressChanged(value) {
    if (this.canUpdateProgress) {
      this.passed = value * this.width;
    }
  }
  private convertTime = function(time) {
    function _convert(decimal) {
      const m = Math.floor(decimal / 60);
      decimal = decimal - m * 60;
      const s = decimal;
      let ret = (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s;
      return ret;
    }
    const decimal = Math.floor(time);

    return _convert(decimal);
  };
  private mounted() {
    this.width = (<Element>this.$refs.progress).getBoundingClientRect().width;
    d3.select(<Element>this.$refs.timeDisplay).attr(
      "d",
      `
      M${this.svgX},350l0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0z
      `
    );
    d3.select(<Element>this.$refs.g).attr("opacity", 0);
    d3.select(<Element>this.$refs.text)
      .attr("y", 400)
      .attr("font-size", 0);
  }
  private getBubbleOutData() {
    const f0 = () => {
      if (this.svgX < 300) {
        return this.svgX - 180 > 0 ? 180 - this.svgX : 0;
      } else {
        return 300 - this.svgX - 120;
      }
      return -120;
    };
    const f1 = () => {
      if (this.svgX < 300) {
        if (this.svgX < 180) return this.svgX > 80 ? 80 - this.svgX : 0;
        else return -100;
      }
      return -100;
    };
    const f2 = () => {
      if (this.svgX > 440) {
        return -540 + this.svgX;
      }
      return -100;
    };
    const f3 = () => {
      if (this.svgX < 300) {
        return -420 + this.svgX;
      } else {
        return this.svgX < 320
          ? this.svgX - 420
          : -this.width + this.svgX + 180 < 0
          ? -this.width + this.svgX + 180
          : 0;
      }
    };
    const f4 = () => {
      return this.svgX > 80 ? -60 : -this.svgX + 20;
    };
    return `
      M${
        this.svgX
      },350l${f4()},-80h${f0()}c${f1()},0,${f1()},0,${f1()},-100v-50c0,-100,0,-100,100,-100h360c100,0,100,0,100,100v50c0,100,0,100,
    ${f2()},100h${f3()}z
    `;
  }
  private beforeDestroy() {
    
  }
  private handleMouseMove(e: PointerEvent) {
    let val = (this.$store.state.duration * this.hintPos) / this.width;
    if (val < 0) val = 0;
    else if (val > this.$store.state.duration) val = this.$store.state.duration;
    this.currentTime = this.convertTime(val);
    this.showHint = true;
    this.mouseLeave = false;
    this.leavingFlag = false;
    this.hintPos = e.clientX;
    this.hintLeft = this.hintPos - 30;
    this.svgX = 300;
    if (this.hintLeft < 0) {
      this.svgX = this.hintPos * 10;
      if (this.svgX < 0) this.svgX = 0;
      this.hintLeft = 0;
    } else if (this.hintLeft > this.width - 60) {
      this.svgX = (-this.width + 60 + this.hintPos) * 10;
      if (this.svgX > 600) this.svgX = 600;
      this.hintLeft = this.width - 60;
    }
    d3.select(<Element>this.$refs.timeDisplay)
      .attr(
        "d",
        `
      M${this.svgX},350l0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0z
      `
      )
      .attr("opcatity", 0);
    if (!this.mouseHover) {
      //     M300,350l-60,-80h-120c-100,0,-100,0,-100,-100v-50c0,-100,0,-100,100,-100h360c100,0,100,0,100,100v50c0,100,0,100,-100,100h-120z
      //     M300,350L240,270H120C20,270,20,270,20,170V120C20,20,20,20,120,20H480C580,20,580,20,580,120V170C580,270,580,270,480,270H360z
      if (!this.showingFlag) {
        this.showingFlag = true;
        d3.select(<Element>this.$refs.timeDisplay)
          .transition()
          .duration(500)
          .attr("d", this.getBubbleOutData())
          .end()
          .then(() => {
            this.showingFlag = false;
            this.mouseHover = true;
          })
          .catch(() => {});
        d3.select(<Element>this.$refs.g)
          .transition()
          .duration(500)
          .attr("opacity", 1);
        d3.select(<Element>this.$refs.text)
          .transition()
          .duration(500)
          .attr("y", 200)
          .attr("font-size", 150);
      }
    } else {
      d3.select(<Element>this.$refs.timeDisplay).attr(
        "d",
        this.getBubbleOutData()
      );
      d3.select(<Element>this.$refs.g).attr("opacity", 1);
    }

    if (this.mouseDown) {
      this.passed = this.hintPos;
    }
  }
  private handleMouseLeave(e: PointerEvent) {
    this.showHint = false;
    this.mouseHover = false;
    this.mouseDown = false;
    this.showingFlag = false;
    if (!this.leavingFlag) {
      this.leavingFlag = true;
      d3.select(<Element>this.$refs.timeDisplay)
        .transition()
        .duration(500)
        .attr(
          "d",
          `
      M${this.svgX},350l0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0c0,0,0,0,0,0v0c0,0,0,0,0,0h0z
      `
        )
        .end()
        .then(() => {
          this.leavingFlag = false;
        })
        .catch(() => {});
      d3.select(<Element>this.$refs.g)
        .transition()
        .duration(500)
        .attr("opacity", 0);
      d3.select(<Element>this.$refs.text)
        .transition()
        .duration(500)
        .attr("y", 400)
        .attr("font-size", 0);
    }
  }
  private handleMouseDown(e: PointerEvent) {
    this.mouseDown = true;
    this.canUpdateProgress = false;
    this.passed = this.hintPos;
    (<Element>this.$refs.progress).setPointerCapture(e.pointerId);
  }
  private handleMouseUp(e: PointerEvent) {
    if (this.mouseDown) {
      // seek
      window.ipcRenderer.send("seek", this.hintPos / this.width);
    }
    this.mouseDown = false;
    (<Element>this.$refs.progress).releasePointerCapture(e.pointerId);
    this.canUpdateProgress = true;
  }
}
</script>

<style lang="scss" scoped>
.progress {
  position: absolute;
  bottom: 0;
  height: 20px;
  left: 0;
  right: 0;
  border-top: 0.5px solid white;
  border-radius: 0 0 6px 6px;
  overflow: hidden;
  cursor: pointer;
  @keyframes passing {
    from {
      background-position-x: 0px;
    }
    to {
      background-position-x: 20px;
    }
  }
  .passed {
    float: left;
    height: 100%;
    background-size: 20px 20px;
    animation: passing 0.5s linear 0s infinite;
  }
  .left {
    height: 100%;
    overflow: hidden;
  }
  .hintLine {
    position: absolute;
    height: 20px;
    top: 0;
    border-left: 1px solid lightgray;
  }
}
.hint {
  position: absolute;
  bottom: -10px;
  height: 60px;
  width: 60px;
  pointer-events: none;
}
</style>
